//
//  FileManager+Extension.swift
//  YangFoundation
//
//  Created by yuyang on 2021/12/21.
//

import Foundation

public extension FileManager {
    var documentDirectoryPath: String {
        return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    }
    
    var cachesDirectoryPath: String {
        return NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
    }
    
    var tempDirectoryPath: String {
        return NSTemporaryDirectory()
    }
}

public extension FileManager {
    func documentDirectory(with folder: String) -> String {
        let path = (documentDirectoryPath as NSString).appendingPathComponent(folder)
        if !FileManager.default.directoryExistAtPath(path) {
            _ = FileManager.default.createDirectoryAtPath(path)
        }
        return path
    }
    
    func cachesDirectory(with folder: String) -> String {
        let path = (cachesDirectoryPath as NSString).appendingPathComponent(folder)
        if !FileManager.default.directoryExistAtPath(path) {
            _ = FileManager.default.createDirectoryAtPath(path)
        }
        return path
    }
    
    func tempDirectory(with folder: String) -> String {
        let path = (tempDirectoryPath as NSString).appendingPathComponent(folder)
        if !FileManager.default.directoryExistAtPath(path) {
            _ = FileManager.default.createDirectoryAtPath(path)
        }
        return path
    }
    
    func isDirectory(_ path: String) -> Bool {
        var isDir : ObjCBool = false
        FileManager.default.fileExists(atPath: path, isDirectory:&isDir)
        return isDir.boolValue
    }
    
    func fileExistsAtPath(_ path: String) -> Bool {
        return FileManager.default.fileExists(atPath: path)
    }
    
    func directoryExistAtPath(_ path: String) -> Bool {
        var isDir : ObjCBool = false
        let fileExist: Bool = FileManager.default.fileExists(atPath: path, isDirectory:&isDir)
        return isDir.boolValue && fileExist
    }
    
    @discardableResult
    func createDirectoryAtPath(_ path: String) -> Bool {
        do {
            try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: false, attributes: nil)
        } catch {
            print("File: \(error)")
            return false
        }
        return true
    }
    
    func getAllFile(_ path: String) -> [String] {
        var filePath: [String] = []
        do {
            let files = try FileManager.default.contentsOfDirectory(atPath: path)
            
            for file in files {
                let fullPath = "\(path)/\(file)"
                if FileManager.default.fileExists(atPath: fullPath) {
                    filePath.append(fullPath)
                }
            }
        } catch let error as NSError {
            print("getAllFile error: \(error)")
        }
        
        return filePath
    }
    
    @discardableResult
    func removeFileAtPath(_ path: String) -> Bool {
        do {
            try FileManager.default.removeItem(atPath: path)
        } catch {
            print(error)
            return false
        }
        return true
    }
    
    @discardableResult
    func removeFileAtDirectory(_ directory: String) -> Bool {
        do {
            for path in try FileManager.default.contentsOfDirectory(atPath: directory) {
                try FileManager.default.removeItem(atPath: "\(directory)" + "/" + "\(path)")
            }
        } catch {
            print(error)
            return false
        }
        return true
    }
    
    @discardableResult
    func moveFileAtPath(_ fromPath: String, toPath path:String) -> Bool {
        do {
            try FileManager.default.moveItem(atPath: fromPath, toPath: path)
        } catch {
            print(error)
            return false
        }
        return true
    }
    
    @discardableResult
    func copyFileAtPath(_ fromPath: String, toPath path:String) -> Bool {
        do {
            try FileManager.default.copyItem(atPath: fromPath, toPath: path)
        } catch {
            print(error)
            return false
        }
        return true
    }
    
    /// 单位：byte
    func fileSizeAtPath(_ path: String) -> Float? {
        guard fileExists(atPath: path) else { return nil }
        guard let fileSize = try? attributesOfItem(atPath: path)[.size] as? NSNumber else {
            return nil
        }
        return fileSize.floatValue
    }
    
    @discardableResult
    func saveImageAtPath(image: UIImage, path: String) -> Bool {

        guard let data = image.pngData() else {
            return false 
        }
        
        do {
            try data.write(to: URL(fileURLWithPath: path))
        } catch {
            print(error)
            return false
        }
        return true
    }
    
    @discardableResult
    func saveDataAtPath(data: Data, path: String) -> Bool {
        do {
            try data.write(to: URL(fileURLWithPath: path))
        } catch {
            print(error)
            return false
        }
        return true
    }
}
